package com.yunhe.authority.service.authority.impl;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.yunhe.authority.domain.authority.*;
import com.yunhe.authority.domain.company.Employee;
import com.yunhe.authority.service.authority.TokenService;
import com.yunhe.common.constant.SystemConsts;
import com.yunhe.common.util.RSAUtil;
import com.yunhe.common.util.RedisClient;
import com.yunhe.common.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.yunhe.common.util.CollectionUtil;

import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.Date;

/**
 * Toekn服务类
 * @author liuronglei
 */
@Service
public class TokenServiceImpl implements TokenService {
    @Autowired
    private RedisClient redisClient;
    private static final String PRIVATE_KEY_STRING = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC+vB8ji8Od19y6VBssY8vOQPKXkzY9NUGQs/dmTXMyJ2f8IvdVzScOzSzTAYuuQErwQ5+eL4tbiUJ5VRrH515ow4TBGjju6zxO7qX8W6qt8IjkR/AsJLLUG3CGNbpqjJEG+Wd4hm7ePJVfC95I8hzX0/HmAvCquYDn5O7uW/4l4M/9fhbT5v9dXlSev/DJVtD9//ypmOkFn7AddeoWwWYMpo2Y+7CKS10t0ovdXgs7zWAV1g01jlg54kU+LTZO47s5pV7Z+pM1ruoFsU5yvYo9iu/5Z/ZUNN2RdrVi4vYBWijlRCY3x2sPmxkMYAOuD9PMQNVTzqYDYO1y76p7IrujAgMBAAECggEAL61ao0oGheg1lqX7fOcdRNtbSKRVxIsRbpht2Ta2+ux6w74B0YLMppiHAd+7CL2tfc2JksMTtLfk0+uAHEQrh0iIYLSrUp2en6Rr/V70lTIxJc8NrBsoUHjjccjwZj3o6rNhN/FyuT6vn+iZkeZja1fhebt2aVahcFX7m72HE/RlfaC7jd2vk9nyeJW6fnxPzKt+ThW3l/aE21jgNlY360w16d40aQ5EZNeh6UDO5o4k8R2hXRpTA0LheLrFXURN4k/Rw72Hxf2DdVLq7JpnbTxEu8ukOhy3RgxpJcI9BEMakua6P1s1OQbbkRqXhpaqRJnGWr47oPPivtVzncWBIQKBgQDujQqBhwRIS5bUTS4+LaiIpTmw1NWKicHsIMcipPuQdBtVkEF2B9Qhi0lZxawjqkHHTIzqGxYWQxnREx6I3Q8n9lZG2Yool2Jgaa/6T0CUAQJDzVoB5JeoKdaCPCgLUFwReBVfY4MYNy03rdLyBA9yQ6LqGPtjVKBGJKU2SfRNmwKBgQDMr7Sqmygzd4SU8BXabBGSTyjTAqy3D+nxFqCow/auGT64zG/fEpEGpHEmU8jnrBg/MXIad0Rn4aA3+rwyfdZGtnPg2Hn83MlXtxir4CWLYqMVHxQMiVo9xNRf/3QlYNMavUQS5k8Q3W22/WFlx+iNXOxh3HX2R59feSsBaLOumQKBgG/Sm6cmJGLDVDvGxjONcaBEW2vCCSu88bN/lflufyIy2xFb4uOyPcVPpp23ZL7/M4B6KOAgvFTJNZPlM34SqeUgu0bQ+MuYUxxAzqY2el4mruobm+KhRlok6pH4IwlSrSXfNZ2WZ0B1tPORvv2F27vDat3zwfvJEqxuxydQuX2bAoGBALSea7eMmMnpsnXW8gG/ETZhYe3p00zq3w4eYIDsA7aXklByHlnjQVRyMWKX1pYQt4iz8jNGgXeFkuMy/3Uys63MfK6xd9vZXFZpvHyWm6rGzI/rz75MSfRtxtY7TltZeI+E6hgfYS/JpXIvXw34fM6ZbAHjD7jWdN1Dx95DbSMpAoGAHgc/AUyuCTJQLpYFH8EJpfqSVeZjnOdIMuQ7WUTnujRMpYhIDa4CT6ozQUzJ0M0u4xYSZTFLy3IOQKyPqqZlVy5pRhLIYsEDybpuTEg24nd0QDm4u3maZUQC51MwrSmuCD1qIMk4d3eq+KH1aLEa9mrIyHKPAl6UhM2gW6/kdMA=";
    private static final String PUBLIC_KEY_STRING = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvrwfI4vDndfculQbLGPLzkDyl5M2PTVBkLP3Zk1zMidn/CL3Vc0nDs0s0wGLrkBK8EOfni+LW4lCeVUax+deaMOEwRo47us8Tu6l/FuqrfCI5EfwLCSy1BtwhjW6aoyRBvlneIZu3jyVXwveSPIc19Px5gLwqrmA5+Tu7lv+JeDP/X4W0+b/XV5Unr/wyVbQ/f/8qZjpBZ+wHXXqFsFmDKaNmPuwiktdLdKL3V4LO81gFdYNNY5YOeJFPi02TuO7OaVe2fqTNa7qBbFOcr2KPYrv+Wf2VDTdkXa1YuL2AVoo5UQmN8drD5sZDGADrg/TzEDVU86mA2Dtcu+qeyK7owIDAQAB";

    private static final String LOGOUT_PRIVATE_KEY_STRING = "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCgKgPb8quTpyDH\n" +
            "HwOC65thNGmhdfyrz1SNFQqezbijX0kV6r1kKAa7s7KJa1zEHOUcHOfzQIdZgCis\n" +
            "51f+y67ycnB94jVZQR6XftLe6MkQnD1bVGee0UC5Azk6mz6YYxr2VbgUeI5K8++e\n" +
            "av+b1chsjBAe89UJr5+jXMRq7SHcO5M71xEB9h87UWlGl1obo4sTDAmSnFFh6Al5\n" +
            "7M/JA7Q3Ej7vpY2t3MzxQlUWTDfNcKpFHoI++lbbHjo0edGImCiVq6++uzq58PMO\n" +
            "I5pTvA4oFEKDRtKPa7zuRj50fJ5bA6V6x8xVpPQFLCTYWiWo+PmPtk3xRkXtSPWm\n" +
            "GKS4YIIHAgMBAAECggEBAIZgWdaKtmtuODD4E1EfbcDTYaCGxlQ74jtwIPX1sejY\n" +
            "BBCwXvAOKQAIl012V2FuwMaidfT/+c8cmIPgoVJz/7cITts/E/Vrjkgarr843aDj\n" +
            "BROAMGPuOng/fR9vqsfdtnxglM4QC4pVOYBXU1eiuMJhjRD7EI1M3QoJxf3UMKl9\n" +
            "uo5RpLKsNI3fy/0b4mQlwu+BHEGoBrqAeqN9umfIBMC3W3FJODCU9L4PO6kpUYI8\n" +
            "k7iQfMr8Bt0sFZVIZfw+AtnK8V2QcdcYoNI5cqCHTVoArOqYDMbB84m0vK4NPIWs\n" +
            "iLuxugEpcfXUnxkKq8yFi8kt0tIhBB0aaEGQbMEiZqkCgYEAzRbyxtpfEk/0IkDb\n" +
            "Kyj3dOI5Ys7XgGs4rEaHtbP6lA73vYB/D9N7PCopASR90P6PZE+UXJOTuaHzmQzI\n" +
            "Q/t2gBlRDNKjPZGHdrT9XkLMUQ9+/+ODyZWvq/d5AsNz0rq4TYlCDIsMySfwWCwi\n" +
            "7vfK05z2WQ/1e1iLwTmeV2r9kIUCgYEAx+wi7c4Z34eL9Q/Wu7Ft9+mnYtQByXqw\n" +
            "vKP09S614u8VUEn/n2YtCrHgunyvRjvD3zuJ8f4Q0BZQNl9J6vswuCKGlPiXPpHN\n" +
            "tjwTwtQu3g7Kr6S03GzH9eMveneFfn0wb4iM4O6XUJpa0R7e8Kwi6/Ak9ufYA4HR\n" +
            "8Kr0ov1udBsCgYEAsCo0JAdTfsFa7UlUeYBY/veLX4pYpiBzr9dtnvCYHzG0L/z+\n" +
            "J7P6uTVlv2t+/1SKCxooUFUboWqxehf2th58LZCRhDgyrCIjgB37PUqXglGTP25I\n" +
            "t5FyMn8CXRNSnAJzaXarW2bddrRtyO8wmqASgy7ilKIWtPrcIP/DOUfXwpkCgYEA\n" +
            "sEcb/UbvNVNVKr3OfyzRY/kX6GI7OSX/VDXVNaL8KZ7Z0jONO0Vijb2OA6ERAwKL\n" +
            "kPf0h/WXaYNjMq4OhSz7JkD7Hbub0EXLdtW+LtncgVvVh83Y00rvfXXWVUux33gP\n" +
            "Dyj93w9BSIbxcNahiOCe4h6a2UJQC7eaH3T9xAFmNOUCgYB6chzRqen0WImZPAAL\n" +
            "oKWiNzL5bTU/viWhNrHY9QkmsaPtwx1FNjICmVecIlVbQ+ZSYECS5+z5TXgx7kYZ\n" +
            "Ehru4GLiHgelZLFYo+NiEd9/VoMwPDaxynpsOgVGQTerADkeiLA3wWFCUCzaG4nd\n" +
            "GwIcrbfsp7sFQUZk90k6uqBzyg==";

    private static final String LOGOUT_PUBLIC_KEY_STRING = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoCoD2/Krk6cgxx8Dguub\n" +
            "YTRpoXX8q89UjRUKns24o19JFeq9ZCgGu7OyiWtcxBzlHBzn80CHWYAorOdX/suu\n" +
            "8nJwfeI1WUEel37S3ujJEJw9W1RnntFAuQM5Ops+mGMa9lW4FHiOSvPvnmr/m9XI\n" +
            "bIwQHvPVCa+fo1zEau0h3DuTO9cRAfYfO1FpRpdaG6OLEwwJkpxRYegJeezPyQO0\n" +
            "NxI+76WNrdzM8UJVFkw3zXCqRR6CPvpW2x46NHnRiJgolauvvrs6ufDzDiOaU7wO\n" +
            "KBRCg0bSj2u87kY+dHyeWwOlesfMVaT0BSwk2FolqPj5j7ZN8UZF7Uj1phikuGCC\n" +
            "BwIDAQAB";
    /**
     * 添加值
     * @param key 键
     * @param value 值
     * @param liveTime 过期时间（秒）
     */
    @Override
    public void setString(String key, String value, Integer liveTime) {
        if (liveTime != null) {
            redisClient.set(key, String.valueOf(value), liveTime);
        } else {
            redisClient.set(key, String.valueOf(value));
        }
    }

    /**
     * 获得值
     * @param key 键
     */
    @Override
    public String getString(String key) {
        return redisClient.get(key);
    }

    /**
     * 删除值
     * @param key 键
     */
    @Override
    public void delString(String key) {
        redisClient.del(key);
    }

    /**
     * 是否存在键
     * @param key 键
     */
    @Override
    public boolean hasKey(String key) {
        return redisClient.exists(key);
    }

    /**
     * 生成token
     * @param user 用户对象
     * @param systemId
     */
    @Override
    public String getToken(User user, String systemId) {
        //设置过期时间
        Date expires = new Date(System.currentTimeMillis() + 24 * 60 * 60 * 1000);
        //Date expires = new Date(System.currentTimeMillis() + 60 * 1000);
        Algorithm algorithm;
        try {
            RSAPrivateKey privateKey = RSAUtil.getPrivateKey(PRIVATE_KEY_STRING);
            RSAPublicKey publicKey = RSAUtil.getPublicKey(PUBLIC_KEY_STRING);
            algorithm = Algorithm.RSA256(publicKey, privateKey);
        } catch(Exception e) {
            e.printStackTrace();
            return null;
        }
        String roleId = null;
        if(!CollectionUtil.isEmpty(user.getRole())){
            for (Role role : user.getRole()) {
                if(StringUtil.isEmpty(roleId)){
                    roleId = role.getId().toString();
                }else {
                    roleId = roleId + ","+role.getId();
                }
            }
        }
        String firmId = null;
        if(!CollectionUtil.isEmpty(user.getFirms())){
            for (Firm firm : user.getFirms()) {
                if(StringUtil.isEmpty(firmId)){
                    firmId = firm.getId().toString();
                }else {
                    firmId = firmId + ","+firm.getId();
                }
            }
        }
        String stationId = null;
        if(!CollectionUtil.isEmpty(user.getStations())){
            for (Station station : user.getStations()) {
                if(StringUtil.isEmpty(firmId)){
                    stationId = station.getId().toString();
                }else {
                    stationId = stationId + ","+station.getId();
                }
            }
        }
        return JWT.create().withExpiresAt(expires)
                .withAudience(String.valueOf(user.getId()))
                .withClaim(SystemConsts.HEADER.PHONE.value(), user.getPhone())
                .withClaim(SystemConsts.HEADER.USER_ID.value(), user.getId())
                .withClaim(SystemConsts.HEADER.ROLE_ID.value(),  roleId)
                .withClaim(SystemConsts.HEADER.FIRM_ID.value(), firmId)
                .withClaim(SystemConsts.HEADER.STATION_ID.value(), stationId)
                .withClaim(SystemConsts.HEADER.SYSTEM_ID.value(), systemId)
                .sign(algorithm);
    }

    @Override
    public String getBackToken(BackUser backUser, String systemId) {
        //设置过期时间
        Date expires = new Date(System.currentTimeMillis() + 24 * 60 * 60 * 1000);
        Algorithm algorithm;
        try {
            RSAPrivateKey privateKey = RSAUtil.getPrivateKey(PRIVATE_KEY_STRING);
            RSAPublicKey publicKey = RSAUtil.getPublicKey(PUBLIC_KEY_STRING);
            algorithm = Algorithm.RSA256(publicKey, privateKey);
        } catch(Exception e) {
            e.printStackTrace();
            return null;
        }
        String roleId = null;
        if(!CollectionUtil.isEmpty(backUser.getRole())){
            for (Role role : backUser.getRole()) {
                if(StringUtil.isEmpty(roleId)){
                    roleId = role.getId().toString();
                }else {
                    roleId = roleId + ","+role.getId();
                }
            }
        }
        return JWT.create().withExpiresAt(expires)
                .withAudience(String.valueOf(backUser.getId()))
                .withClaim(SystemConsts.HEADER.PHONE.value(), backUser.getPhone())
                .withClaim(SystemConsts.HEADER.USER_ID.value(), backUser.getId())
                .withClaim(SystemConsts.HEADER.ROLE_ID.value(),  roleId)
                .withClaim(SystemConsts.HEADER.SYSTEM_ID.value(), systemId)
                .sign(algorithm);
    }

    @Override
    public String lostToken(User user) {
        //设置过期时间
        Date expires = new Date(System.currentTimeMillis() + 24 * 60 * 60 * 1000);
        Algorithm algorithm;
        try {
            RSAPrivateKey privateKey = RSAUtil.getPrivateKey(LOGOUT_PRIVATE_KEY_STRING);
            RSAPublicKey publicKey = RSAUtil.getPublicKey(LOGOUT_PUBLIC_KEY_STRING);
            algorithm = Algorithm.RSA256(publicKey, privateKey);
        } catch(Exception e) {
            e.printStackTrace();
            return null;
        }
        String roleId = null;
        if(!CollectionUtil.isEmpty(user.getRole())){
            for (Role role : user.getRole()) {
                if(StringUtil.isEmpty(roleId)){
                    roleId = role.getId().toString();
                }else {
                    roleId = roleId + ","+role.getId();
                }
            }
        }
        String firmId = null;
        if(!CollectionUtil.isEmpty(user.getFirms())){
            for (Firm firm : user.getFirms()) {
                if(StringUtil.isEmpty(firmId)){
                    firmId = firm.getId().toString();
                }else {
                    firmId = firmId + ","+firm.getId();
                }
            }
        }
        String stationId = null;
        if(!CollectionUtil.isEmpty(user.getStations())){
            for (Station station : user.getStations()) {
                if(StringUtil.isEmpty(firmId)){
                    stationId = station.getId().toString();
                }else {
                    stationId = stationId + ","+station.getId();
                }
            }
        }
        return JWT.create().withExpiresAt(expires)
                .withAudience(String.valueOf(user.getId()))
                .withClaim(SystemConsts.HEADER.PHONE.value(), user.getPhone())
                .withClaim(SystemConsts.HEADER.USER_ID.value(), user.getId())
                .withClaim(SystemConsts.HEADER.ROLE_ID.value(),  roleId)
                .withClaim(SystemConsts.HEADER.FIRM_ID.value(), firmId)
                .withClaim(SystemConsts.HEADER.STATION_ID.value(), stationId)
                .withClaim(SystemConsts.HEADER.SYSTEM_ID.value(), user.getLastLoginSystem())
                .sign(algorithm);
    }

    @Override
    public String getAppToken(User user, String systemId) {
        //设置过期时间
        Date expires = new Date(System.currentTimeMillis() + (30*24 * 60 * 60 * 1000L));
        //Date expires = new Date(System.currentTimeMillis() + 60 * 1000);
        Algorithm algorithm;
        try {
            RSAPrivateKey privateKey = RSAUtil.getPrivateKey(PRIVATE_KEY_STRING);
            RSAPublicKey publicKey = RSAUtil.getPublicKey(PUBLIC_KEY_STRING);
            algorithm = Algorithm.RSA256(publicKey, privateKey);
        } catch(Exception e) {
            e.printStackTrace();
            return null;
        }
        String roleId = null;
        if(!CollectionUtil.isEmpty(user.getRole())){
            for (Role role : user.getRole()) {
                if(StringUtil.isEmpty(roleId)){
                    roleId = role.getId().toString();
                }else {
                    roleId = roleId + ","+role.getId();
                }
            }
        }
        String firmId = null;
        if(!CollectionUtil.isEmpty(user.getFirms())){
            for (Firm firm : user.getFirms()) {
                if(StringUtil.isEmpty(firmId)){
                    firmId = firm.getId().toString();
                }else {
                    firmId = firmId + ","+firm.getId();
                }
            }
        }
        String stationId = null;
        if(!CollectionUtil.isEmpty(user.getStations())){
            for (Station station : user.getStations()) {
                if(StringUtil.isEmpty(firmId)){
                    stationId = station.getId().toString();
                }else {
                    stationId = stationId + ","+station.getId();
                }
            }
        }
        return JWT.create().withExpiresAt(expires)
                .withAudience(String.valueOf(user.getId()))
                .withClaim(SystemConsts.HEADER.PHONE.value(), user.getPhone())
                .withClaim(SystemConsts.HEADER.USER_ID.value(), user.getId())
                .withClaim(SystemConsts.HEADER.ROLE_ID.value(),  roleId)
                .withClaim(SystemConsts.HEADER.FIRM_ID.value(), firmId)
                .withClaim(SystemConsts.HEADER.STATION_ID.value(), stationId)
                .withClaim(SystemConsts.HEADER.SYSTEM_ID.value(), systemId)
                .sign(algorithm);
    }

    @Override
    public String getWechatToken(String phone) {
        //设置过期时间
        Date expires = new Date(System.currentTimeMillis() + (30L * 24L * 60L * 60L * 1000L));
        //Date expires = new Date(System.currentTimeMillis() + 60 * 1000);
        Algorithm algorithm;
        try {
            RSAPrivateKey privateKey = RSAUtil.getPrivateKey(PRIVATE_KEY_STRING);
            RSAPublicKey publicKey = RSAUtil.getPublicKey(PUBLIC_KEY_STRING);
            algorithm = Algorithm.RSA256(publicKey, privateKey);
        } catch(Exception e) {
            e.printStackTrace();
            return null;
        }

        return JWT.create().withExpiresAt(expires)
                .withAudience(phone)
                .withClaim(SystemConsts.HEADER.PHONE.value(), phone)
                .sign(algorithm);
    }

}
